'use strict'

const Service = require('egg').Service
const { Op } = require('sequelize')

class TestTestService extends Service {
  /**
   * 查询 post - 权限 open
   * @param {Object} data - 请求参数
   * @param {String} data.test_id - id
   * @param {String} data.test_name - 名称
   * @param {Number} data.pagesize - 每页条数
   * @param {Number} data.pagenum - 页码
   */
  async testList(data) {
    const { ctx, app } = this

    let { pagesize = 20, pagenum = 1 } = data
    pagesize = Number(pagesize)
    pagenum = Number(pagenum)

    // 错误参数处理
    if (pagenum < 1) {
      return ctx.throw(400, { msg: 'pagenum不能小于1' })
    }

    // 数据库连接
    const db = app.model.TestTest
    const dbforeign = app.model.TestTestforeign

    // 查询条件处理
    const conditions = {}

    // 分页
    if (pagesize > 0) {
      conditions.limit = pagesize
      conditions.offset = (pagenum - 1) * pagesize
    }

    // 查询语句
    const quary = {}
    if (data.test_id) {
      quary.test_id = { [Op.like]: `%${data.test_id || ''}%` }
    }
    if (data.test_name) {
      quary.test_name = { [Op.like]: `%${data.test_name || ''}%` }
    }
    conditions.where = quary

    // 其他
    conditions.order = [['created_at', 'ASC']] // 排序
    conditions.attributes = {
      exclude: ['updated_at'] // 排除字段
    }
    conditions.include = [
      {
        model: dbforeign, // 关联的表
        as: 'test_detail',
        attributes: {
          exclude: ['updated_at', 'created_at'] // 排除字段
        }
      }
    ]

    // 查询操作
    const { count, rows } = await db.findAndCountAll(conditions)

    // 总页数
    const pages = pagesize > 0 ? Math.ceil(count / pagesize) : 1

    ctx.result({
      data: rows,
      msg: '列表获取成功',
      total: count,
      pagenum,
      pagesize,
      pages
    })
  }

  /**
   * 新增 post - 权限 open
   * @param {Object} data - 请求参数
   * @param {String} data.test_id - id
   * @param {String} data.test_name - 名称
   * @param {String} data.remark - 备注
   */
  async testAdd(data) {
    const { ctx, app } = this

    data = Object.assign(
      {
        test_id: ''
      },
      data
    )

    if (!data.test_id) {
      return ctx.throw(400, { msg: 'test_id 必填' })
    }

    // 数据库连接
    const db = app.model.TestTest

    // 查询条件处理
    const conditions = { where: { test_id: data.test_id } }

    const one = await db.findOne(conditions)
    if (one) {
      return ctx.throw(400, { msg: '新增项已存在' })
    }

    const res = await db.create(data)

    ctx.result({
      data: res,
      msg: '新增成功'
    })
  }

  /**
   * 更新 post - 权限 open
   * @param {Object} data - 请求参数
   * @param {String} data.test_id - id
   * @param {String} data.test_name - 名称
   * @param {String} data.remark - 备注
   */
  async testUpdate(data) {
    const { ctx, app } = this

    data = Object.assign(
      {
        test_id: ''
      },
      data
    )

    if (!data.test_id) {
      return ctx.throw(400, { msg: 'test_id 必填' })
    }

    // 数据库连接
    const db = app.model.TestTest

    // 查询条件处理
    const conditions = { where: { test_id: data.test_id } }

    const one = await db.findOne(conditions)
    if (!one) {
      return ctx.throw(400, { msg: '更新项不存在' })
    }

    const res = await db.update(data, conditions)

    ctx.result({
      data: res,
      msg: '更新成功'
    })
  }

  /**
   * 删除 post - 权限 open
   * @param {Object} data - 请求参数
   * @param {String} data.test_id - id
   */
  async testDelete(data) {
    const { ctx, app } = this

    if (!data.test_id) {
      return ctx.throw(400, { msg: 'test_id 必填' })
    }

    // 数据库连接
    const db = app.model.TestTest

    // 查询条件处理
    const conditions = { where: { test_id: data.test_id } }

    const one = await db.findOne(conditions)
    if (!one) {
      return ctx.throw(400, { msg: '删除项不存在' })
    }

    const res = await db.destroy(conditions)

    ctx.result({
      data: res,
      msg: '删除成功'
    })
  }

  /**
   * 批量新增 post - 权限 open
   * @param {Object} data - 请求参数
   * @param {Array} data.list 批量新增项
   * @param {Boolean} data.cover - 是否覆盖 默认true
   */
  async testAddBatch(data) {
    const { ctx, app } = this

    data = Object.assign(
      {
        list: [],
        cover: true // 是否覆盖
      },
      data
    )

    if (!Array.isArray(data.list)) {
      return ctx.throw(400, { msg: 'list 必须是数组' })
    }

    if (data.list.length == 0) {
      return ctx.throw(400, { msg: 'list 为空' })
    }

    // 数据库连接
    const db = app.model.TestTest
    // 主键 mysql主键字段设置为UNIQUE，否则将会导致覆盖添加失效
    const primaryKey = 'test_id'
    // 覆盖字段
    const updateOnDuplicate = ['test_id', 'test_name', 'remark']

    // 过滤掉主键缺失无效的项
    data.list = data.list.filter((item) => item[primaryKey])

    // 如果是增量模式
    if (!data.cover) {
      const existingIds = await db.findAll({
        attributes: [primaryKey],
        where: {
          [primaryKey]: {
            [Op.in]: data.list.map((item) => item[primaryKey])
          }
        }
      })

      // 过滤掉已存在的id
      const existingIdsSet = new Set(existingIds.map((item) => item[primaryKey]))
      data.list = data.list.filter((item) => !existingIdsSet.has(item[primaryKey]))
    }

    // 注意：这里不再需要区分cover的options，因为增量逻辑已在之前处理
    const res = await db.bulkCreate(data.list, { validate: true, updateOnDuplicate })

    ctx.result({
      data: res,
      msg: data.cover ? '批量覆盖添加成功' : '批量增量添加成功'
    })
  }

  /**
   * 批量删除 post - 权限 open
   * @param {Object} data - 请求参数
   * @param {Array} data.list - 批量新增项
   */
  async testDeleteBatch(data) {
    const { ctx, app } = this

    data = Object.assign(
      {
        list: [] // 需要删除的记录的ID列表
      },
      data
    )

    if (!Array.isArray(data.list)) {
      return ctx.throw(400, { msg: 'list 必须是数组' })
    }

    if (data.list.length == 0) {
      return ctx.throw(400, { msg: 'list 为空' })
    }

    // 数据库连接
    const db = app.model.TestTest
    // 主键 mysql主键字段设置为UNIQUE，否则将会导致覆盖添加失效
    const primaryKey = 'test_id'

    // 执行批量删除
    const res = await db.destroy({
      where: {
        [primaryKey]: {
          [Op.in]: data.list
        }
      }
    })

    if (res == 0) {
      return ctx.throw(400, { msg: '无有效数据项删除' })
    }

    ctx.result({
      data: res,
      msg: '批量删除成功'
    })
  }
}

module.exports = TestTestService
